package com.xh.easyretry;

import com.xh.easyretry.common.XHRetryContext;
import com.xh.easyretry.strategy.retry.BaseRetryStrategy;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Slf4j
@Component
public class RetryExecutor {

    @Autowired
    private BaseRetryStrategy syncRetryStrategy;

    @Autowired
    private List<BaseRetryStrategy> retryStrategyList;


    public Object doRetry(String strategy, ProceedingJoinPoint pjp) {
        XHRetryContext retryContext = buildRetryContext(pjp);
        BaseRetryStrategy retryStrategy = getRetryStrategy(strategy);
        try {
            return retryStrategy.execRetry(retryContext);
        } catch (Exception e) {
            log.error("RetryExecutor.doRetry msg=重试工具异常，将不再进行重试", e);
        }
        return retryStrategy.buildResult(retryContext);
    }

    private BaseRetryStrategy getRetryStrategy(String strategy) {
        return Optional.ofNullable(retryStrategyList).orElse(Collections.emptyList())
                .stream()
                .filter(strategyImpl -> Objects.equals(strategy, strategyImpl.getStrategy()))
                .findFirst()
                .orElse(syncRetryStrategy);
    }

    private XHRetryContext buildRetryContext(ProceedingJoinPoint pjp) {
        return new XHRetryContext.XHRetryContextBuilder(pjp)
                .buildCurrentRetryCount()
                .buildBeanClass()
                .buildBean()
                .buildMethod()
                .buildArgs()
                .buildXHRetry()
                .buildVisitor()
                .build();
    }
}
